using System.Linq;

namespace ExtendedMvc.Elements {
	public class ValidationMessage<TModel> : ValidationMessageBase<ValidationMessage<TModel>, TModel> where TModel : class {
		public ValidationMessage(IModelViewHelper<TModel> helper, string targetId) : base(helper, targetId) { }
	}

	public abstract class ValidationMessageBase<T, TModel> : LiteralBase<T>
		where T : ValidationMessageBase<T, TModel>
		where TModel : class {
		private const string validationSuffix = "_Error";

		protected IModelViewHelper<TModel> helper { get; private set; }
		protected string targetId { get; private set; }

		protected ValidationMessageBase(IModelViewHelper<TModel> helper, string targetId)
			: base(null, targetId + validationSuffix) {
			this.helper = helper;
			this.targetId = targetId;
		}

		public virtual bool HasError {
			get {
				if (helper.ViewContext.ViewData.ModelState == null || !helper.ViewContext.ViewData.ModelState.ContainsKey(targetId)) return false;
				var modelState = helper.ViewContext.ViewData.ModelState[targetId];
				return (modelState != null && modelState.Errors != null && modelState.Errors.Any());
			}
		}

		private new T Text(string value) {
			base.Text(value);
			return (T)this;
		}

		public virtual T DefaultMessage(string value) {
			this.Text(value);
			return (T)this;
		}

		public virtual string ErrorMessage {
			get {
				if (!HasError) return null;
				return text ?? helper.ViewContext.ViewData.ModelState[targetId].Errors[0].ErrorMessage;
			}
		}

		protected override void Prepare() {
			CssClass("field-validation-error");
			base.Prepare();
		}

		protected override void SetContent() {
			this.Text(ErrorMessage);
			base.SetContent();
		}

		public override string ToString() {
			if (!HasError) return string.Empty;
			return base.ToString();
		}
	}
}
